<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MyBatis常见异常解析 - 开发指南</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', sans-serif;
            color: #333;
            line-height: 1.6;
        }
        h1, h2, h3, h4 {
            font-family: 'Noto Serif SC', serif;
            font-weight: 600;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #6e8efb 0%, #a777e3 100%);
        }
        .card-hover {
            transition: all 0.3s ease;
        }
        .card-hover:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1);
        }
        .code-block {
            background-color: #2d3748;
            color: #e2e8f0;
            border-radius: 0.375rem;
            overflow-x: auto;
        }
        .exception-tag {
            position: absolute;
            top: -12px;
            right: 20px;
            background-color: #f56565;
            color: white;
            padding: 0.25rem 0.75rem;
            border-radius: 9999px;
            font-size: 0.75rem;
            font-weight: 600;
        }
    </style>
</head>
<body class="bg-gray-50">
    <!-- Hero Section -->
    <section class="hero-gradient text-white py-20 px-4">
        <div class="container mx-auto max-w-6xl">
            <div class="flex flex-col md:flex-row items-center">
                <div class="md:w-1/2 mb-10 md:mb-0">
                    <h1 class="text-4xl md:text-5xl font-bold mb-4">MyBatis异常解析手册</h1>
                    <p class="text-xl opacity-90 mb-6">开发者必备的数据库操作问题解决方案</p>
                    <div class="flex flex-wrap gap-4">
                        <a href="#result-set" class="bg-white text-purple-700 hover:bg-gray-100 px-6 py-3 rounded-lg font-medium transition duration-300">结果集封装</a>
                        <a href="#primary-key" class="bg-purple-800 hover:bg-purple-900 text-white px-6 py-3 rounded-lg font-medium transition duration-300">主键异常</a>
                        <a href="#field-issues" class="bg-white text-purple-700 hover:bg-gray-100 px-6 py-3 rounded-lg font-medium transition duration-300">字段问题</a>
                    </div>
                </div>
                <div class="md:w-1/2">
                    <div class="bg-white bg-opacity-20 p-6 rounded-xl backdrop-blur-sm border border-white border-opacity-20">
                        <div class="mermaid">
                            graph TD
                            A[MyBatis常见异常] --> B[结果集封装异常]
                            A --> C[主键自增异常]
                            A --> D[字段不存在异常]
                            A --> E[字段长度异常]
                            A --> F[Mapper配置异常]
                            B --> B1[缺少resultMap/resultType]
                            C --> C1[未设置自增主键]
                            D --> D1[表字段缺失]
                            E --> E1[数据长度不匹配]
                            F --> F1[未注册Mapper文件]
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <div class="container mx-auto max-w-6xl px-4 py-12">
        <!-- Result Set Exception -->
        <section id="result-set" class="mb-20">
            <div class="relative bg-white rounded-xl shadow-lg overflow-hidden card-hover">
                <div class="exception-tag">结果集异常</div>
                <div class="p-8">
                    <h2 class="text-3xl font-bold text-gray-800 mb-6">MyBatis结果集封装的异常</h2>
                    
                    <div class="mb-8">
                        <h3 class="text-xl font-semibold text-gray-700 mb-3">异常截图</h3>
                        <img src="https://cdn.nlark.com/yuque/0/2021/png/21449790/1631516476940-dfcf0142-37af-4ff0-ba70-df68826186bd.png" 
                             alt="结果集封装异常截图" 
                             class="w-full rounded-lg border border-gray-200">
                    </div>
                    
                    <div class="grid md:grid-cols-2 gap-8">
                        <div>
                            <h3 class="text-xl font-semibold text-gray-700 mb-3">异常原因</h3>
                            <p class="text-gray-600 mb-6">MyBatis执行SQL语句后，获取到数据库返回的结果集不知道封装到哪个对象。</p>
                            
                            <h3 class="text-xl font-semibold text-gray-700 mb-3">如何解决</h3>
                            <p class="text-gray-600">给select标签设置resultMap或者resultType属性</p>
                        </div>
                        
                        <div class="code-block p-6">
                            <pre class="text-sm"><code class="language-xml">
&lt;!-- 解决方案示例 --&gt;
&lt;select id="selectUser" <span class="text-yellow-300">resultType="com.example.User"</span>&gt;
    SELECT * FROM users WHERE id = #{id}
&lt;/select&gt;

&lt;!-- 或者使用resultMap --&gt;
&lt;resultMap id="userResultMap" type="com.example.User"&gt;
    &lt;id property="id" column="id"/&gt;
    &lt;result property="name" column="user_name"/&gt;
&lt;/resultMap&gt;

&lt;select id="selectUser" <span class="text-yellow-300">resultMap="userResultMap"</span>&gt;
    SELECT id, user_name FROM users WHERE id = #{id}
&lt;/select&gt;
                            </code></pre>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Primary Key Exception -->
        <section id="primary-key" class="mb-20">
            <div class="relative bg-white rounded-xl shadow-lg overflow-hidden card-hover">
                <div class="exception-tag">主键异常</div>
                <div class="p-8">
                    <h2 class="text-3xl font-bold text-gray-800 mb-6">主键自增的异常</h2>
                    
                    <div class="mb-8">
                        <h3 class="text-xl font-semibold text-gray-700 mb-3">异常截图</h3>
                        <img src="https://cdn.nlark.com/yuque/0/2021/png/21449790/1631517925669-f6a8470b-705a-4cf3-87a0-cde153b278df.png" 
                             alt="主键自增异常截图" 
                             class="w-full rounded-lg border border-gray-200">
                    </div>
                    
                    <div class="grid md:grid-cols-2 gap-8">
                        <div>
                            <h3 class="text-xl font-semibold text-gray-700 mb-3">异常原因</h3>
                            <p class="text-gray-600 mb-6">主键的特点唯一，非空。没有给主键设置值</p>
                            
                            <h3 class="text-xl font-semibold text-gray-700 mb-3">如何解决</h3>
                            <p class="text-gray-600">让主键自增</p>
                            
                            <h3 class="text-xl font-semibold text-gray-700 mb-3 mt-4">如何避免</h3>
                            <p class="text-gray-600">在设计表结构时明确主键的自增策略</p>
                        </div>
                        
                        <div class="code-block p-6">
                            <pre class="text-sm"><code class="language-xml">
&lt;!-- MySQL自增主键配置 --&gt;
&lt;insert id="insertUser" <span class="text-yellow-300">useGeneratedKeys="true" keyProperty="id"</span>&gt;
    INSERT INTO users(name, email) VALUES(#{name}, #{email})
&lt;/insert&gt;

&lt;!-- 对应数据库表设计 --&gt;
CREATE TABLE users (
    <span class="text-yellow-300">id INT PRIMARY KEY AUTO_INCREMENT</span>,
    name VARCHAR(50),
    email VARCHAR(100)
);
                            </code></pre>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Field Not Exist Exception -->
        <section id="field-issues" class="mb-20">
            <div class="relative bg-white rounded-xl shadow-lg overflow-hidden card-hover">
                <div class="exception-tag">字段异常</div>
                <div class="p-8">
                    <h2 class="text-3xl font-bold text-gray-800 mb-6">数据库表字段不存在异常</h2>
                    
                    <div class="mb-8">
                        <h3 class="text-xl font-semibold text-gray-700 mb-3">异常截图</h3>
                        <img src="https://cdn.nlark.com/yuque/0/2021/png/21449790/1631606942727-02db868e-905d-437b-b93c-aadc8639aec3.png" 
                             alt="字段不存在异常截图" 
                             class="w-full rounded-lg border border-gray-200">
                    </div>
                    
                    <div class="grid md:grid-cols-2 gap-8">
                        <div>
                            <h3 class="text-xl font-semibold text-gray-700 mb-3">异常原因</h3>
                            <p class="text-gray-600 mb-4">1、你访问的字段数据库表中不存在</p>
                            
                            <h3 class="text-xl font-semibold text-gray-700 mb-3">如何解决</h3>
                            <p class="text-gray-600 mb-2">1、表中没有定义这个字段</p>
                            <p class="text-gray-600">2、使用注解忽略这个字段</p>
                        </div>
                        
                        <div class="code-block p-6">
                            <pre class="text-sm"><code class="language-java">
// 解决方案1: 添加字段到数据库表
ALTER TABLE users ADD COLUMN <span class="text-yellow-300">new_field</span> VARCHAR(255);

// 解决方案2: 使用@Transient注解忽略字段
public class User {
    private Integer id;
    private String name;
    
    <span class="text-yellow-300">@Transient</span>
    private String tempField; // 不会被MyBatis映射
}
                            </code></pre>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Field Length Exception -->
        <section class="mb-20">
            <div class="relative bg-white rounded-xl shadow-lg overflow-hidden card-hover">
                <div class="exception-tag">长度异常</div>
                <div class="p-8">
                    <h2 class="text-3xl font-bold text-gray-800 mb-6">数据库字段长度异常</h2>
                    
                    <div class="mb-8">
                        <h3 class="text-xl font-semibold text-gray-700 mb-3">异常截图</h3>
                        <img src="https://cdn.nlark.com/yuque/0/2021/png/21449790/1631687239010-044f98ae-2753-45d6-b014-adcd316c0e18.png" 
                             alt="字段长度异常截图" 
                             class="w-full rounded-lg border border-gray-200">
                    </div>
                    
                    <div class="grid md:grid-cols-2 gap-8">
                        <div>
                            <h3 class="text-xl font-semibold text-gray-700 mb-3">异常原因</h3>
                            <p class="text-gray-600 mb-6">数据库接受的长度和实际插入的长度不一致</p>
                            
                            <h3 class="text-xl font-semibold text-gray-700 mb-3">如何解决</h3>
                            <p class="text-gray-600 mb-2">1、修改字段的长度</p>
                            <p class="text-gray-600">2、修改页面传递的数据</p>
                            
                            <h3 class="text-xl font-semibold text-gray-700 mb-3 mt-4">如何避免</h3>
                            <p class="text-gray-600">设计表字段的时候必须要结合业务数据来设计</p>
                        </div>
                        
                        <div class="code-block p-6">
                            <pre class="text-sm"><code class="language-sql">
-- 解决方案1: 修改字段长度
ALTER TABLE products 
MODIFY COLUMN description <span class="text-yellow-300">VARCHAR(2000)</span>;

-- 解决方案2: 前端验证数据长度
// JavaScript示例
if (product.description.length > 2000) {
    alert('描述内容过长，请控制在2000字符以内');
    return false;
}
                            </code></pre>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Mapper Not Registered Exception -->
        <section class="mb-20">
            <div class="relative bg-white rounded-xl shadow-lg overflow-hidden card-hover">
                <div class="exception-tag">配置异常</div>
                <div class="p-8">
                    <h2 class="text-3xl font-bold text-gray-800 mb-6">Mapper文件没有注册</h2>
                    
                    <div class="mb-8">
                        <h3 class="text-xl font-semibold text-gray-700 mb-3">异常截图</h3>
                        <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1664160801315-07fde444-6bef-4e51-aec1-18f87b060808.png" 
                             alt="Mapper未注册异常截图" 
                             class="w-full rounded-lg border border-gray-200">
                    </div>
                    
                    <div class="grid md:grid-cols-2 gap-8">
                        <div>
                            <h3 class="text-xl font-semibold text-gray-700 mb-3">异常原因</h3>
                            <p class="text-gray-600 mb-6">在MyBaits的核心配置文件中没有指定Mapper文件。</p>
                            
                            <h3 class="text-xl font-semibold text-gray-700 mb-3">异常如何解决</h3>
                            <p class="text-gray-600 mb-4">在mybatis-config.xml中配置Mapper文件即可。</p>
                            <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1664160905603-4c09f1ca-127f-4a2b-8817-666902d4cab2.png" 
                                 alt="Mapper配置解决方案" 
                                 class="w-full rounded-lg border border-gray-200">
                        </div>
                        
                        <div class="code-block p-6">
                            <pre class="text-sm"><code class="language-xml">
&lt;!-- mybatis-config.xml 配置 --&gt;
&lt;configuration&gt;
    &lt;mappers&gt;
        <span class="text-yellow-300">&lt;mapper resource="com/example/mapper/UserMapper.xml"/&gt;</span>
        &lt;!-- 或者使用包扫描 --&gt;
        <span class="text-yellow-300">&lt;package name="com.example.mapper"/&gt;</span>
    &lt;/mappers&gt;
&lt;/configuration&gt;
                            </code></pre>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Method Parameter Not Found -->
        <section class="mb-20">
            <div class="relative bg-white rounded-xl shadow-lg overflow-hidden card-hover">
                <div class="exception-tag">参数异常</div>
                <div class="p-8">
                    <h2 class="text-3xl font-bold text-gray-800 mb-6">方法的参数没有找到</h2>
                    
                    <div class="mb-8">
                        <h3 class="text-xl font-semibold text-gray-700 mb-3">异常截图</h3>
                        <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1664178817711-188e155e-9775-4c0d-b7ed-9c576a0d4077.png" 
                             alt="参数未找到异常截图" 
                             class="w-full rounded-lg border border-gray-200">
                    </div>
                    
                    <div class="grid md:grid-cols-2 gap-8">
                        <div>
                            <h3 class="text-xl font-semibold text-gray-700 mb-3">异常的原理</h3>
                            <p class="text-gray-600 mb-4">Mapepr.xml中不是按照方法形参的名称来找的。</p>
                            <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1664178948033-400ef05c-7952-4a01-ab7e-2370af70397b.png" 
                                 alt="参数映射原理" 
                                 class="w-full rounded-lg border border-gray-200">
                        </div>
                        
                        <div class="code-block p-6">
                            <pre class="text-sm"><code class="language-java">
// 解决方案1: 使用@Param注解指定参数名
public interface UserMapper {
    User selectById(<span class="text-yellow-300">@Param("userId")</span> Integer id);
}

// 对应Mapper.xml
&lt;select id="selectById" resultType="User"&gt;
    SELECT * FROM users WHERE id = <span class="text-yellow-300">#{userId}</span>
&lt;/select&gt;

// 解决方案2: 使用参数索引(不推荐)
&lt;select id="selectById" resultType="User"&gt;
    SELECT * FROM users WHERE id = <span class="text-yellow-300">#{0}</span>
&lt;/select&gt;
                            </code></pre>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Missing resultType Attribute -->
        <section class="mb-20">
            <div class="relative bg-white rounded-xl shadow-lg overflow-hidden card-hover">
                <div class="exception-tag">结果映射</div>
                <div class="p-8">
                    <h2 class="text-3xl font-bold text-gray-800 mb-6">Mapper.xml中没有设置resultType属性</h2>
                    
                    <div class="mb-8">
                        <h3 class="text-xl font-semibold text-gray-700 mb-3">异常截图</h3>
                        <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1664179138095-816b4649-f733-4be4-b293-8a8e188066ed.png" 
                             alt="缺少resultType异常截图" 
                             class="w-full rounded-lg border border-gray-200">
                    </div>
                    
                    <div class="grid md:grid-cols-2 gap-8">
                        <div>
                            <h3 class="text-xl font-semibold text-gray-700 mb-3">异常的原理</h3>
                            <p class="text-gray-600">MyBatis执行完SQL语句后得到了结果集，不知道把结果集给你封装到那个实体类中，所以需要设置resultType属性。</p>
                        </div>
                        
                        <div class="code-block p-6">
                            <pre class="text-sm"><code class="language-xml">
&lt;!-- 错误的写法 --&gt;
&lt;select id="selectUsers"&gt;
    SELECT * FROM users
&lt;/select&gt;

&lt;!-- 正确的写法 --&gt;
&lt;select id="selectUsers" <span class="text-yellow-300">resultType="com.example.User"</span>&gt;
    SELECT * FROM users
&lt;/select&gt;

&lt;!-- 或者使用resultMap --&gt;
&lt;resultMap id="userResultMap" type="com.example.User"&gt;
    &lt;!-- 字段映射配置 --&gt;
&lt;/resultMap&gt;

&lt;select id="selectUsers" <span class="text-yellow-300">resultMap="userResultMap"</span>&gt;
    SELECT * FROM users
&lt;/select&gt;
                            </code></pre>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Mapper Method Returns Multiple Values -->
        <section>
            <div class="relative bg-white rounded-xl shadow-lg overflow-hidden card-hover">
                <div class="exception-tag">返回类型</div>
                <div class="p-8">
                    <h2 class="text-3xl font-bold text-gray-800 mb-6">Mapper方法返回多个值</h2>
                    
                    <div class="mb-8">
                        <h3 class="text-xl font-semibold text-gray-700 mb-3">异常截图</h3>
                        <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1664184150744-fbb1137c-db74-4494-a8ea-3ae89f5e4614.png" 
                             alt="返回多个值异常截图" 
                             class="w-full rounded-lg border border-gray-200">
                    </div>
                    
                    <div class="grid md:grid-cols-2 gap-8">
                        <div>
                            <h3 class="text-xl font-semibold text-gray-700 mb-3">异常的原因</h3>
                            <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1664184190531-42437700-ec1c-4039-8ef1-7c31f2bfeadb.png" 
                                 alt="返回多个值解决方案" 
                                 class="w-full rounded-lg border border-gray-200">
                            <p class="text-gray-600 mt-4">方法上使用List来接收多个结果。</p>
                        </div>
                        
                        <div class="code-block p-6">
                            <pre class="text-sm"><code class="language-java">
// Mapper接口定义
public interface UserMapper {
    <span class="text-yellow-300">List&lt;User&gt;</span> selectAllUsers();
}

// 对应的Mapper.xml
&lt;select id="selectAllUsers" resultType="com.example.User"&gt;
    SELECT * FROM users
&lt;/select&gt;

// 服务层调用
public class UserService {
    private UserMapper userMapper;
    
    public List&lt;User&gt; getAllUsers() {
        return userMapper.selectAllUsers();
    }
}
                            </code></pre>
                        </div>
                    </div>
                </div>
            </div>
        </section>
    </div>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
    </script>
</body>
</html>